package com.nnnu.orange.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nnnu.orange.constant.BookStatusConstants;
import com.nnnu.orange.constant.MessageConstants;
import com.nnnu.orange.exception.ObjectNullException;
import com.nnnu.orange.mapper.AuthorsMapper;
import com.nnnu.orange.mapper.BooksMapper;
import com.nnnu.orange.pojo.dto.AuthorsDto;
import com.nnnu.orange.pojo.dto.AuthorsQueryDto;
import com.nnnu.orange.pojo.entity.Authors;
import com.nnnu.orange.pojo.entity.Books;
import com.nnnu.orange.result.PageResult;
import com.nnnu.orange.service.IAuthorsService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 存储作者的详细信息 服务实现类
 * </p>
 *
 * @author zk
 * @since 2024-11-07
 */
@Service
@RequiredArgsConstructor
public class AuthorsServiceImpl extends ServiceImpl<AuthorsMapper, Authors> implements IAuthorsService {
    private final BooksMapper booksMapper;

    /**
     * 新增作者
     *
     * @param dto dto
     */
    @Override
    public void save(AuthorsDto dto) {
        save(BeanUtil.copyProperties(dto, Authors.class));
    }

    /**
     * 修改作者相关信息
     *
     * @param dto dto
     */
    @Override
    public void update(AuthorsDto dto) {
        if (dto == null || dto.getAuthorId() == null) {
            throw new ObjectNullException(MessageConstants.NULL);
        }
        updateById(BeanUtil.copyProperties(dto, Authors.class));
    }

    /**
     * 分页查询作者列表
     *
     * @param queryDto dto
     * @return 分页后的列表
     */
    @Override
    public PageResult<Authors> list(@NotNull AuthorsQueryDto queryDto) {
        String name = queryDto.getName();
        String bio = queryDto.getBio();
        String nationality = queryDto.getNationality();

        // 判断是否需要分页
        boolean isPagination = queryDto.getPageNum() != null && queryDto.getPageSize() != null
                && queryDto.getPageNum() > 0 && queryDto.getPageSize() > 0;


        Page<Authors> authorsPage;
        if (isPagination) {
            authorsPage = baseMapper.selectPage(
                    new Page<>(queryDto.getPageNum(), queryDto.getPageSize()),
                    new LambdaQueryWrapper<Authors>()
                            .or().like(!StringUtils.isBlank(name), Authors::getName, name)
                            .or().like(!StringUtils.isBlank(bio), Authors::getBio, bio)
                            .or().like(!StringUtils.isBlank(nationality), Authors::getNationality, nationality)
            );
        } else {
            // 不分页，查询所有数据
            authorsPage = new Page<>(1, Integer.MAX_VALUE);
            List<Authors> authors = baseMapper.selectList(
                    new LambdaQueryWrapper<Authors>()
                            .or().like(!StringUtils.isBlank(name), Authors::getName, name)
                            .or().like(!StringUtils.isBlank(bio), Authors::getBio, bio)
                            .or().like(!StringUtils.isBlank(nationality), Authors::getNationality, nationality)
            );
            authorsPage.setTotal(authors.size()).setRecords(authors);
        }
        return new PageResult<>(authorsPage.getTotal(), authorsPage.getRecords());
    }


    /**
     * 批量删除作者
     *
     * @param ids ids
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteBatch(@NotNull List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new ObjectNullException(MessageConstants.NULL);
        }
        List<Integer> list = ids.stream().distinct().toList();
        List<String> messages = new ArrayList<>();


        list.forEach(id -> {
            Long count = booksMapper.selectCount(new LambdaQueryWrapper<Books>().eq(Books::getAuthorId, id)
                    .in(Books::getStatus,
                            BookStatusConstants.ON_SHELF,  // 上架中
                            BookStatusConstants.CHECKED_OUT, // 已借出
                            BookStatusConstants.RESERVED,    // 预定
                            BookStatusConstants.UNDER_REPAIR));// 维修中
            if (count > 0) {
                messages.add("作者id " + id + " 存在书籍在上架");
            }
        });
        if (!CollectionUtils.isEmpty(messages)) {
            throw new ObjectNullException(MessageConstants.DELETE_FAILED + ":" + StringUtils.join(",", messages));
        }
        return baseMapper.deleteBatchIds(list) > 0;
    }
}
